from django.http import HttpResponse
from apps.user.models import User, Address
from apps.goods.models import GoodsSKU
from django.shortcuts import render, redirect
from django.urls import reverse
from django.core.mail import send_mail
from django.views.generic import View
from django.conf import settings

from loguru import logger
import re
from itsdangerous import TimedJSONWebSignatureSerializer as Serializer
from itsdangerous import SignatureExpired
# from celery_tasks.tasks import send_register_active_email
from django.contrib.auth import authenticate, login, logout
# from utils.mixin import LoginRequiredMinxin
from django.contrib.auth.mixins import LoginRequiredMixin
from django_redis import get_redis_connection


# Create your views here.

def register(request):
    if request.method == 'GET':
        return render(request, 'register.html')
        # 接收数据
    username = request.POST.get('user_name')
    password = request.POST.get('pwd')
    cpassword = request.POST.get('cpwd')
    email = request.POST.get('email')
    allow = request.POST.get('allow')
    logger.info(f'{username},{password},{cpassword},{email},{allow}')
    # 进行数据校验
    if not all([username, password, email]):
        return render(request, 'register.html', {'err_msg': '注册信息有误，请重新输入'})
    # 邮箱验证
    if not re.match('^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$', email):
        return render(request, 'register.html', {'err_msg': '邮箱格式不正确，请重新输入'})
    # 验证两次密码
    if password != cpassword:
        return render(request, 'register.html', {'err_msg': '两次密码输入不一致，请重新输入'})
    # 协议勾选验证
    if allow != 'on':
        return render(request, 'register.html', {'err_msg': '请勾选”天天生鲜用户使用协议“'})
    # 校验用户名是否存在
    try:
        user = User.objects.get(username=username)
    except User.DoesNotExist:
        user = None
    if user:
        return render(request, 'register.html', {'err_msg': '用户名已存在'})
    user = User.objects.create_user(username, email, password)
    user.is_active = 0
    user.save()
    logger.info(user)

    return redirect(reverse('goods:index'))


class RegisterView(View):

    def get(self, request):
        return render(request, 'register.html')

    def post(self, request):
        # 接收数据
        username = request.POST.get('user_name')
        password = request.POST.get('pwd')
        cpassword = request.POST.get('cpwd')
        email = request.POST.get('email')
        allow = request.POST.get('allow')
        logger.info(f'{username},{password},{cpassword},{email},{allow}')
        # 进行数据校验
        if not all([username, password, email]):
            return render(request, 'register.html', {'err_msg': '注册信息有误，请重新输入'})
        # 邮箱验证
        if not re.match('^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$', email):
            return render(request, 'register.html', {'err_msg': '邮箱格式不正确，请重新输入'})
        # 验证两次密码
        if password != cpassword:
            return render(request, 'register.html', {'err_msg': '两次密码输入不一致，请重新输入'})
        # 协议勾选验证
        if allow != 'on':
            return render(request, 'register.html', {'err_msg': '请勾选”天天生鲜用户使用协议“'})
        # 校验用户名是否存在
        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            user = None
        if user:
            return render(request, 'register.html', {'err_msg': '用户名已存在'})
        user = User.objects.create_user(username, email, password)
        user.is_active = 0
        user.save()
        logger.info(user)
        # 发送激活邮件，包含激活链接: http://127.0.0.1:8000/user/active/3
        # 激活链接中需要包含用户的身份信息, 并且要把身份信息进行加密

        # 加密用户的身份信息，生成激活token
        serializer = Serializer(settings.SECRET_KEY, 3600)
        info = {'confirm': user.id}
        token = serializer.dumps(info)
        token = token.decode('utf8')
        # 发邮件
        # send_register_active_email.delay(email, username, token)
        # 发邮件
        subject = '天天生鲜欢迎信息'
        message = ''
        sender = settings.EMAIL_FROM
        receiver = [email]
        html_message = f'<h1>{username},欢迎您注册成为天天生鲜欢会员</h1>请点击以下链接激活你的账户<a href="http://127.0.0.1:8001/user/active/{token}">http://127.0.0.1:8001/user/active/{token}</a>'
        send_mail(subject, message, sender, receiver, html_message=html_message)
        return redirect(reverse('goods:index'))


class ActiveView(View):
    """用户激活"""

    def get(self, request, token):
        """进行用户激活"""
        serializer = Serializer(settings.SECRET_KEY, 3600)
        try:
            info = serializer.loads(token)
            # 获取待激活用户的id
            user_id = info['confirm']
            # 根据id获取用户信息
            user = User.objects.get(id=user_id)
            user.is_active = 1
            user.save()
            # 跳转到登录页面
            return redirect(reverse('user:login'))
        except SignatureExpired as e:
            # 激活链接已过期
            return HttpResponse('激活链接已过期')


class LoginView(View):
    """登录"""

    def get(self, request):
        """显示登录页面"""
        # 判断是否记住了用户名
        if 'username' in request.COOKIES:
            username = request.COOKIES.get('username')
            checked = 'checked'
        else:
            username = ''
            checked = ''
        return render(request, 'login.html', locals())

    def post(self, request):
        """登录校验"""
        username = request.POST.get('username')
        password = request.POST.get('pwd')
        remember = request.POST.get('remember')
        # 校验数据
        if not all([username, password]):
            return render(request, 'login.html', {'err_msg': '登录信息有误，请重新输入。'})
        user = authenticate(username=username, password=password)
        logger.info(f'{user}')
        # 校验用户名是否存在
        try:
            user = User.objects.get(username=username)
        except User.DoesNotExist:
            return render(request, 'login.html', {'err_msg': '用户不存在，请重新输入。'})
        if user is not None:
            # 用户名密码㠪确
            if user.is_active:
                # 用户已激活
                login(request, user)
                # 获取登录后所要跳转的地址
                next_url = request.GET.get('next', reverse('goods:index'))
                # 跳转到next_url
                response = redirect(next_url)
                # 判断是否需要记住用户名
                if remember == 'on':
                    response.set_cookie('username', username, max_age=7 * 24 * 3600)
                else:
                    response.delete_cookie('username')
                return response
            else:
                # 用户未激活
                return render(request, 'login.html', {'err_msg': '用户未激活'})
        else:
            return render(request, 'login.html', {'err_msg': '用户名或密码错误'})


class LogoutView(View):
    """退出"""

    def get(self, request):
        """退出登录"""
        # 清除用户session信息
        logout(request)
        # 跳转到首页
        return redirect(reverse('goods:index'))


class UserInfoView(LoginRequiredMixin, View):
    """用户中心-显示页"""

    def get(self, request):
        """显示"""
        curr_page = 'user'
        # 获取个人信息
        user = request.user
        address = Address.objects.get_default_address(user)
        # 获取用户历史浏览记录
        # from redis import StrictRedis
        # str = StrictRedis(host='127.0.0.1', port=6379, db=9)
        conn = get_redis_connection('default')
        history_key = f'history_{user.id}'
        # 获取用户最新浏览的五个商品的id
        sku_ids = conn.lrange(history_key, 0, 4)
        # 遍历获取用户浏览的商品信息
        goods_li = []
        for id in sku_ids:
            goods = GoodsSKU.objects.get(id=id)
            goods_li.append(goods)
        return render(request, 'user_center_info.html', locals())


class UserOrderView(LoginRequiredMixin, View):
    """用户中心-订单页"""

    def get(self, request):
        """显示"""
        curr_page = 'order'
        return render(request, 'user_center_order.html', locals())


class AdressView(LoginRequiredMixin, View):
    """用户中心-地址页"""

    def get(self, request):
        """显示"""
        curr_page = 'address'
        # 获取登录用户
        user = request.user
        # 获取用户默认收货地址
        # try:
        #     address = Address.objects.get(user=user, is_default=True)
        #     logger.info(f'{address.user}, {address.addr}, {address.phone},{address.is_default}')
        # except Address.DoesNotExist:
        #     address = None
        address = Address.objects.get_default_address(user)
        return render(request, 'user_center_site.html', locals())

    def post(self, request):
        # 接收数据
        receiver = request.POST.get('receiver')
        addr = request.POST.get('addr')
        zip_code = request.POST.get('zip_code')
        phone = request.POST.get('phone')
        # 校验数据
        if not all([receiver, addr, phone]):
            return render(request, 'user_center_site.html', {'err_msg': '提交数据有误，请重新输入'})
        # 校验手机号
        if not re.match('^(13[0-9]|14[5|7]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\d{8}$', phone):
            return render(request, 'user_center_site.html', {'err_msg': '手机号码有误，请重新输入'})
        # 业务处理
        # 如果用户已存在默认地址，添加的地址不作为默认收货地址，否则作为默认收货地址
        user = request.user
        # try:
        #     address = Address.objects.get(user=user, is_default=True)
        # except Address.DoesNotExist:
        #     address = None
        address = Address.objects.get_default_address(user)

        if address:
            is_default = False
        else:
            is_default = True
        Address.objects.create(user=user, receiver=receiver, addr=addr, zip_code=zip_code, phone=phone,
                               is_default=is_default)
        # 返回应答
        return redirect(reverse('user:address'))
